﻿using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace $rootnamespace$.$subnamespace$
{
    public interface I$safeitemrootname$
    {
        #region Observer pattern implementation for the controller that observe the view
        I$subnamespace$Controller Observer { get; }
        bool Subscribe(I$subnamespace$Controller controller);
        bool UnSubscribe(I$subnamespace$Controller controller);
        #endregion

        void AddModel(I$subnamespace$Model view);
    }

    /// <summary>
    /// A view is a (visual) representation of its model. It would ordinarily highlight certain attributes
    /// thers. It is thus acting as a presentation filter.
    /// A view is attached to its model (or model part) and gets the data necessary for the presentation
    /// from the model by asking questions. It may also update the model by sending appropriate
    /// messages. All these questions and messages have to be in the terminology of the model, the
    /// view will therefore have to know the semantics of the attributes of the model it represents. (It
    /// may, for example, ask for the model's identifier and expect an instance of Text, it may not
    /// assume that the model is of class Text.)
    /// </summary>
    public class $safeitemrootname$ : Control, I$safeitemrootname$
    {
        /// <summary>
        /// Controller that are observing this view
        /// </summary>
        private I$subnamespace$Controller observer;

        /// <summary>
        /// All the models that the view belongs to
        /// </summary>
        private List<I$subnamespace$Model> models;

        /// <summary>
        /// View contructor
        /// </summary>
        public $subnamespace$View()
        {
            InitView();
        }

        /// <summary>
        /// View constructor
        /// </summary>
        /// <param name="model">Model that the view belongs to</param>
        public $subnamespace$View(I$subnamespace$Model model)
        {
            InitView();

            // Add the model to the view
            AddModel(model);
        }

        /// <summary>
        /// View constructor
        /// </summary>
        /// <param name="modelList">List of models that the view belongs to</param>
        public $subnamespace$View(List<I$subnamespace$Model> modelList)
        {
            InitView();

            // Add all the models in the list to the view
            foreach (var model in modelList) AddModel(model);
        }

        /// <summary>
        /// View destructor
        /// </summary>
        ~$subnamespace$View()
        {
            // Stop observing the models
            foreach (var model in models) model.UnSubscribe(this);
        }

        void InitView()
        {
            // Start off with no models
            models = new List<I$subnamespace$Model>();

            // Add some controls to the view
            AddUiControls();
        }

        public void AddModel(I$subnamespace$Model model)
        {
            // Subscribe to the model
            model.Subscribe(this);

            models.Add(model);
        }

        /// <summary>
        /// Add some user interface controls to the view
        /// </summary>
        void AddUiControls()
        {
            // Add an example message 
            MessageText = new Label { Text = "MVC web part for SharePoint 2010" };
            this.Controls.Add(MessageText);

            // Add an example submit button
            SubmitButton = new Button { Text = "Get my completed tasks" };
            this.Controls.Add(SubmitButton);

        }

        /// <summary>
        /// Example of an event method that will have its events fired from the controller
        /// </summary>
        public void RefreshTaskList(List<string> tasks)
        {
            if (tasks.Count == 0)
            {
                MessageText.Text = "You have no completed tasks";
                return;
            }

            StringBuilder sb = new StringBuilder();
            foreach (var task in tasks) sb.AppendFormat("{0}<br>", task);
            MessageText.Text = sb.ToString();
        }

        #region Controls that are part of this view

        /// <summary>
        /// Example of a button in the view
        /// </summary>
        public Button SubmitButton { get; private set; }

        /// <summary>
        /// Example of a message in the view
        /// </summary>
        public Label MessageText { get; private set; }

        #endregion

        #region Observer pattern that allows views to subscribe to controller events

        /// <summary>
        /// Returns the controller that observes this view
        /// </summary>
        I$subnamespace$Controller I$subnamespace$View.Observer
        {
            get { return observer; }
        }

        /// <summary>
        /// Allows a controller to unsubscribe from the view
        /// </summary>
        /// <param name="view">View that wants to unsubscribe</param>
        /// <returns>True if success, false if failed</returns>
        bool I$subnamespace$View.UnSubscribe(I$subnamespace$Controller controller)
        {
            // Check if there is controller that is a subscriber
            if (observer == null) return false;
            observer = null;
            return true;
        }

        /// <summary>
        /// Allows a view to subscribe to events from its controller
        /// </summary>
        /// <param name="view">View that wants to subscribe</param>
        bool I$subnamespace$View.Subscribe(I$subnamespace$Controller controller)
        {
            // Don't allow a controller to take over a view without that controlling having unsubscribed
            if (observer != null) return false;
            observer = controller;
            return true;
        }
        #endregion

    }
}
